#Web应用主入口
from flask import Flask, render_template, request, jsonify, session, redirect, url_for
from main import KnowledgeExplanationAgent
from config import FLASK_SECRET_KEY, DEFAULT_USERS, DEBUG_MODE
from model_status import model_status
from multimodal_enhancer import multimodal_enhancer
from knowledge_enhancer import zhiyuan_enhancer
import json
import os
from functools import wraps
from tempfile import NamedTemporaryFile
import subprocess

app = Flask(__name__)
app.config['SECRET_KEY'] = FLASK_SECRET_KEY

# 初始化知识解释智能体
agent = KnowledgeExplanationAgent()

def login_required(f):
    """登录验证装饰器"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            return redirect(url_for('login'))
        return f(*args, **kwargs)
    return decorated_function

@app.route('/')
def index():
    """重定向到登录页面"""
    return redirect(url_for('login'))

@app.route('/login', methods=['GET', 'POST'])
def login():
    """登录页面"""
    if request.method == 'POST':
        data = request.get_json()
        username = data.get('username')
        password = data.get('password')
        
        if username in DEFAULT_USERS and DEFAULT_USERS[username]['password'] == password:
            session['user_id'] = username
            session['user_role'] = DEFAULT_USERS[username]['role']
            session['user_name'] = DEFAULT_USERS[username]['name']
            return jsonify({'status': 'success', 'redirect': '/dashboard'})
        else:
            return jsonify({'status': 'error', 'message': '用户名或密码错误'}), 401
    
    return render_template('login.html')

@app.route('/logout')
def logout():
    """登出"""
    session.clear()
    return redirect(url_for('login'))

@app.route('/dashboard')
@login_required
def dashboard():
    """主页面（需要登录）"""
    return render_template('index.html', user=session)

@app.route('/code_editor')
@login_required
def code_editor():
    return render_template('code_editor.html', user=session)

@app.route('/practice')
@login_required
def practice():
    """Rust练习智能体页面"""
    return render_template('practice.html', user=session)

@app.route('/api/chat', methods=['POST'])
@login_required
def chat():
    """聊天API接口"""
    try:
        data = request.get_json()
        user_id = session.get('user_id', 'anonymous')
        message = data.get('message', '').strip()
        
        if not message:
            return jsonify({
                'status': 'error',
                'message': '消息不能为空'
            }), 400
        
        # 调用知识解释智能体处理问题
        result = agent.process_question(user_id, message)
        
        return jsonify(result)
        
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'服务器错误: {str(e)}'
        }), 500

@app.route('/api/status')
def status():
    """系统状态检查"""
    return jsonify({
        'status': 'success',
        'message': '系统运行正常',
        'version': '1.0.0',
        'model_status': model_status.get_status_summary()
    })

@app.route('/api/export', methods=['POST'])
def export_chat():
    """导出聊天记录"""
    try:
        data = request.get_json()
        chat_history = data.get('history', [])
        
        # 生成导出文件
        export_data = {
            'timestamp': data.get('timestamp'),
            'user_id': data.get('user_id'),
            'history': chat_history
        }
        
        return jsonify({
            'status': 'success',
            'data': export_data
        })
        
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'导出失败: {str(e)}'
        }), 500

@app.route('/api/knowledge', methods=['GET'])
def get_knowledge():
    """获取知识库信息"""
    try:
        # 这里可以返回知识库统计信息
        return jsonify({
            'status': 'success',
            'data': {
                'total_docs': len(agent.retriever.knowledge_base),
                'categories': ['definition', 'usage', 'error_debug', 'comparison', 'faq']
            }
        })
        
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'获取知识库信息失败: {str(e)}'
        }), 500

@app.route('/api/session/<session_id>', methods=['GET'])
def get_session(session_id):
    """获取会话信息"""
    try:
        context = agent.context_manager.get_context(session_id)
        summary = agent.context_manager.get_session_summary(session_id)
        
        return jsonify({
            'status': 'success',
            'data': {
                'context': context,
                'summary': summary
            }
        })
        
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'获取会话信息失败: {str(e)}'
        }), 500

@app.route('/api/session/<session_id>', methods=['DELETE'])
def clear_session(session_id):
    """清空会话"""
    try:
        agent.context_manager.clear_context(session_id)
        
        return jsonify({
            'status': 'success',
            'message': '会话已清空'
        })
        
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'清空会话失败: {str(e)}'
        }), 500

@app.route('/api/storage/stats', methods=['GET'])
@login_required
def get_storage_stats():
    """获取存储统计信息"""
    try:
        stats = agent.context_manager.get_storage_stats()
        return jsonify({
            'status': 'success',
            'stats': stats
        })
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'获取存储统计失败: {str(e)}'
        }), 500

@app.route('/api/render', methods=['POST'])
def render_markdown():
    """渲染Markdown为HTML"""
    try:
        data = request.get_json()
        markdown_content = data.get('markdown', '')
        
        if not markdown_content:
            return jsonify({
                'status': 'error',
                'message': 'Markdown内容不能为空'
            }), 400
        
        # 使用多模态增强器
        enhanced_content = multimodal_enhancer.enhance_content(markdown_content)
        
        return jsonify({
            'status': 'success',
            'html': enhanced_content['enhanced_html'],
            'code_blocks': enhanced_content['code_blocks'],
            'mermaid_diagrams': enhanced_content['mermaid_diagrams'],
            'tables': enhanced_content['tables']
        })
        
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'渲染失败: {str(e)}'
        }), 500

@app.route('/api/multimodal/styles')
def get_multimodal_styles():
    """获取多模态增强样式"""
    try:
        css_styles = multimodal_enhancer.generate_css_styles()
        return jsonify({
            'status': 'success',
            'css': css_styles
        })
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'获取样式失败: {str(e)}'
        }), 500

@app.route('/api/multimodal/scripts')
def get_multimodal_scripts():
    """获取多模态增强脚本"""
    try:
        js_functions = multimodal_enhancer.generate_js_functions()
        return jsonify({
            'status': 'success',
            'javascript': js_functions
        })
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'获取脚本失败: {str(e)}'
        }), 500

@app.route('/api/zhiyuan/stats', methods=['GET'])
@login_required
def get_zhiyuan_stats():
    """获取智源研究院知识统计"""
    try:
        stats = zhiyuan_enhancer.get_knowledge_statistics()
        return jsonify({
            'status': 'success',
            'stats': stats
        })
    except Exception as e:
        return jsonify({
            'status': 'error',
            'message': f'获取统计信息失败: {str(e)}'
        }), 500

@app.route('/api/run_rust_code', methods=['POST'])
@login_required
def run_rust_code():
    """运行Rust代码并返回结果"""
    try:
        data = request.get_json()
        code = data.get('code', '')
        if not code:
            return jsonify({'status': 'error', 'message': '代码不能为空'}), 400
        # 写入临时文件
        with NamedTemporaryFile('w', encoding='utf-8', suffix='.rs', delete=False) as f:
            f.write(code)
            rust_file = f.name
        exe_file = rust_file[:-3] + '.exe'
        # 编译
        compile_proc = subprocess.run(['rustc', rust_file, '-o', exe_file], capture_output=True, text=True, timeout=10)
        if compile_proc.returncode != 0:
            return jsonify({'status': 'error', 'message': '编译错误', 'stderr': compile_proc.stderr})
        # 运行
        run_proc = subprocess.run([exe_file], capture_output=True, text=True, timeout=5)
        return jsonify({'status': 'success', 'stdout': run_proc.stdout, 'stderr': run_proc.stderr})
    except subprocess.TimeoutExpired:
        return jsonify({'status': 'error', 'message': '运行超时'}), 500
    except Exception as e:
        return jsonify({'status': 'error', 'message': f'运行失败: {str(e)}'}), 500

@app.route('/api/analyze_rust_code', methods=['POST'])
@login_required
def analyze_rust_code():
    """调用大模型分析Rust代码，返回分析结果"""
    from answer_generator import AnswerGenerator
    try:
        data = request.get_json()
        code = data.get('code', '')
        examples_raw = data.get('examples', '')
        if not code:
            return jsonify({'status': 'error', 'message': '代码不能为空'}), 400
        # 解析 examples
        try:
            examples = json.loads(examples_raw) if examples_raw else {}
        except Exception as e:
            examples = {}
        code_practice = examples.get('code_practice', '')
        comprehensive_case = examples.get('comprehensive_case', '')
        # 构造更详细的分析prompt
        prompt = f"""
你是一个专业的Rust编程题目批改与优化专家。请根据下方的【题目内容】和【用户提交代码】，完成如下分析：

【题目内容】
{code_practice}\n{comprehensive_case}

【用户提交代码】
```rust
{code}
```

请严格按照以下结构输出：

1. **题目归属判断**：判断该代码最有可能是针对哪一道题目（请给出题号和题目标题/内容，若无法判断请说明原因）。
2. **正确性分析**：判断代码是否正确，若有错误请详细指出并给出修改建议。
3. **优化建议**：从风格、性能、安全性等角度给出具体可操作的优化建议。
4. **完美代码示例**：给出针对该题目的最优/标准Rust代码（用```rust代码块包裹）。
5. **正向反馈**：指出该代码的优点、亮点或值得肯定的地方，鼓励用户继续学习。

请用分点详细说明，内容要简明、专业、鼓励性强。
"""
        ag = AnswerGenerator()
        # 直接用Gemini API分析
        try:
            gemini_payload = {
                "contents": [
                    {"parts": [
                        {"text": prompt}
                    ]}
                ]
            }
            headers = {
                "Content-Type": "application/json",
                "X-goog-api-key": ag.gemini_api_key
            }
            import requests
            resp = requests.post(ag.gemini_url, json=gemini_payload, headers=headers, timeout=30)
            if resp.status_code == 200:
                data = resp.json()
                if "candidates" in data and data["candidates"]:
                    content = data["candidates"][0]["content"]["parts"][0]["text"]
                    return jsonify({'status': 'success', 'result': content})
                else:
                    raise Exception("Gemini无有效分析结果")
            else:
                raise Exception(f"Gemini API错误: {resp.status_code} {resp.text}")
        except Exception as e:
            return jsonify({'status': 'error', 'message': f'大模型分析失败: {str(e)}'})
    except Exception as e:
        return jsonify({'status': 'error', 'message': f'服务器错误: {str(e)}'})

@app.errorhandler(404)
def not_found(error):
    return jsonify({
        'status': 'error',
        'message': '接口不存在'
    }), 404

@app.errorhandler(500)
def internal_error(error):
    return jsonify({
        'status': 'error',
        'message': '服务器内部错误'
    }), 500

if __name__ == '__main__':
    # 确保静态文件目录存在
    os.makedirs('static/css', exist_ok=True)
    os.makedirs('static/js', exist_ok=True)
    os.makedirs('templates', exist_ok=True)
    
    print("启动Rust知识解释智能体Web服务...")
    print("访问地址: http://localhost:5001")
    print("API文档: http://localhost:5001/api/status")
    
    app.run(debug=DEBUG_MODE, host='0.0.0.0', port=5001)